/**
 * @file adpt_otdr.c
 * @synopsis  
 * @author wen wjcapple@163.com
 * @version v2.0
 * @date 2016-12-13
 */
#include "global.h"
#include "hb_app.h"
#include"adpt_otdr.h"
#ifdef __cplusplus
extern "C" {
#endif
//通道测量结果	
struct _tagOtdrTestCtrl otdrTestCtrl;

/* --------------------------------------------------------------------------*/
/**
 * @synopsis  get_ch_otdr_curv 
 *
 * @param ch		通道，0 开始
 * @param pch_para 	网络协议格式的通道参数
 * @param pch_tr	测量结果
 *
 * @returns   		0 成功，其他错误码
 */
/* ----------------------------------------------------------------------------*/
int32_t get_ch_otdr_curv(
	       	int32_t ch,
	       	const struct _tagCHPara *pch_para,
		OtdrTestResult_t *pch_tr,
		_tagSpiDevCtrl *spi_ctrl,
		int (*stop)(void))
{
	int32_t ret;
	ret = CMD_RET_PARA_INVLADE;
	OtdrTestParam_t algor_para;

	if(ch < 0 || ch > CH_NUM || pch_para == NULL || pch_tr == NULL || spi_ctrl == NULL)
		goto usr_exit;
	memset(&algor_para, 0, sizeof(OtdrTestParam_t));
	algor_para.ChanNum = ch;	
	algor_para.OtdrMode = 1;
	algor_para.slice_ms = 4000;
	algor_para.RefreshPeriod_ms = pch_para->MeasureTime_ms;
	algor_para.DataNum = DATA_LEN;
	memcpy(&algor_para.Lambda_nm, pch_para,sizeof(struct _tagCHPara));
	algor_para.Lambda_nm = otdrDev[ch].ch_ctrl.lamda;
	

	ret = startTest(&algor_para, cb_cpy_tr, pch_tr, stop, (DeviceInfo_t *)spi_ctrl);
usr_exit:
	return ret;
}
int32_t get_cyc_curv_from_algor(
		struct _tagCycCurv *pCycCurv, 
		OtdrTestResult_t *pch_tr,
		int32_t ch)
{
	int32_t ret;
	struct _tagHostOtdrPara *phost_para;
	struct _tagOtdrEvent *HostEptbuf;
	struct _tagUpOtdrCurv *pcurv;
	struct _tagHostTestResult *pHostTr;
	ret = 0;
	pcurv = &pCycCurv->curv;
	phost_para = (struct _tagHostOtdrPara *)&pcurv->para;
	HostEptbuf = (struct _tagOtdrEvent *)pcurv->event.buf;
	pHostTr = (struct _tagHostTestResult *)&pcurv->result.chain;
	quick_lock(&pCycCurv->lock);

	phost_para->slot = card_slot;
	convert_para_algor2host(&pch_tr->tp, phost_para);

	strcpy(pcurv->event.id,"KeyEvents\0");
	pcurv->event.num = pch_tr->EventNum;
	convert_event_algor2host(pch_tr,HostEptbuf,pch_tr->EventNum);

	strcpy(pcurv->data.id, "OTDRData\0");
	pcurv->data.num = pch_tr->tp.DataNum;
	convert_data_algor2host(pch_tr,pcurv->data.buf,pcurv->data.num);


	strcpy(pcurv->result.id, "OTDRTestResultInfo\0");
	convert_tr_algor2host(pch_tr, pHostTr);
	quick_unlock(&pCycCurv->lock);
	return ret;
}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  convert_para_host2algor 	将测量参数从用户配置格式转换到算法格式
 *
 * @param phost_para	配置参数格式
 * @param palgor_para	算法模块参数格式	
 *
 * @returns   0成功，其他错误码
 */
/* ----------------------------------------------------------------------------*/
int32_t convert_para_host2algor(
		const struct _tagHostOtdrPara *phost_para,
		struct _tagCHPara *palgor_para
		)
{
	palgor_para->EndThreshold = phost_para->EndThreshold;
	palgor_para->Lambda_nm = phost_para->Lambda_nm;
	palgor_para->MeasureLength_m = phost_para->MeasureLength_m;
	palgor_para->MeasureTime_ms = phost_para->MeasureTime_s * 1000;
	palgor_para->NonRelectThreshold = phost_para->NonRelectThreshold;
	palgor_para->PulseWidth_ns = phost_para->PulseWidth_ns;
	palgor_para->n = phost_para->n;
	
	return 0;
}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  convert_para_algor2host 
 *
 * @param palgor_para	配置参数格式
 * @param phost_para	算法参数
 *
 * @returns   0
 */
/* ----------------------------------------------------------------------------*/
int32_t convert_para_algor2host(
		const OtdrTestParam_t *palgor_para,
		 struct _tagHostOtdrPara *phost_para)
{
	phost_para->EndThreshold = palgor_para->EndThreshold;
	phost_para->Lambda_nm = palgor_para->Lambda_nm;
	phost_para->MeasureLength_m = palgor_para->MeasureLength_m;
	phost_para->MeasureTime_s = palgor_para->MeasureTime_ms / 1000;
	phost_para->NonRelectThreshold = palgor_para->NonReflex;
	phost_para->PulseWidth_ns = palgor_para->PulseWidth_ns;
	phost_para->n = palgor_para->n;
	phost_para->pipe = palgor_para->ChanNum;
	phost_para->sample_hz = palgor_para->SampleRate_Hz;
	phost_para->rsv2 = palgor_para->rsvd1;
	phost_para->rsv3 = palgor_para->rsvd2;

	return 0;
}
//曲线信息中的测量结果，算法-->协议模式
int32_t convert_tr_algor2host(
		const OtdrTestResult_t *tr, 
		struct _tagHostTestResult * pHostTr)
{
	pHostTr->attu = tr->FiberAttenCoef;
	pHostTr->chain = tr->FiberLen;
	pHostTr->loss = tr->FiberLoss;
	return 0;
}
//事件点，算法-->协议模式
int32_t convert_event_algor2host(
		const OtdrTestResult_t *tr,
		struct _tagOtdrEvent HostEptbuf[],
		int32_t ept_num_max )
{
	int32_t i, ept_num;
	ept_num = tr->EventNum;
	if(ept_num > ept_num_max)
		ept_num = ept_num_max;
	//开始事件没有衰减系数
	i = 0;
	HostEptbuf[i].attu = 0; 
	HostEptbuf[i].distance = tr->ep[i].EventStart;
	HostEptbuf[i].insert_loss = tr->ep[i].EventInsertloss;
	HostEptbuf[i].return_loss = tr->ep[i].EventReturnloss;
	HostEptbuf[i].total_loss = tr->ep[i].EventTotalloss;
	HostEptbuf[i].type = tr->ep[i].EventType;

	for(i = 1; i < ept_num;i++)
	{
		HostEptbuf[i].attu = tr->fs[i-1].FiberSectionAttenCoef;
		HostEptbuf[i].distance = tr->ep[i].EventStart;
		HostEptbuf[i].insert_loss = tr->ep[i].EventInsertloss;
		HostEptbuf[i].return_loss = tr->ep[i].EventReturnloss;
		HostEptbuf[i].total_loss = tr->ep[i].EventTotalloss;
		HostEptbuf[i].type = tr->ep[i].EventType;
	}
	return 0;

}
//数据点，算法-->协议模式
int32_t convert_data_algor2host(
		const OtdrTestResult_t *tr,
		uint16_t data_buf[],
		int max_data_num)
{
	int i ,data_num;
	data_num = tr->tp.DataNum;
	if(data_num > max_data_num)
		data_num = max_data_num;

	for(i = 0; i < data_num;i++)
	{
		data_buf[i] = tr->Ai[i]*1000;
	}
	return 0;


}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  cb_cpy_tr 回调函数，算法程序调用，将测试结果拷贝给用户
 *
 * @param tr_dsti	用户数据缓存
 * @param tr_src	算法数据缓存
 * @param error_code	错误码
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
int32_t cb_cpy_tr(OtdrTestResult_t * tr_dst, OtdrTestResult_t *tr_src, int32_t error_code)
{
	int32_t ret,i;
	char evattr;	//sor格式中事件属性，次低八位
	int32_t event_type;
	OtdrTestParam_t *ptp;
	if(error_code != 0){

		PR_X("algro ret %d\n", error_code);
		goto usr_exit;
	}
	ret = check_algro_tr(tr_src);
	if(ret != 0){

		PR_X("algro data illegality %d\n", ret);
		goto usr_exit;
	}
	//valid tp Ai ep 
	tr_dst->valid = tr_src->valid;
	memcpy(&tr_dst->tp, &tr_src->tp, sizeof(OtdrTestParam_t));
	ptp = &tr_dst->tp;
	for(i = 0; i < ptp->DataNum;i++)
	{
		tr_dst->Ai[i] = tr_src->Ai[i] + 5;
	}
	tr_dst->tp.DataNum -= 1000;
	tr_dst->EventNum = tr_src->EventNum;
	memcpy(tr_dst->ep, tr_src->ep, sizeof(EventPoint_t)*MAX_EVENT_NUM);
	tr_dst->ep[0].EventType = EVENT_TYPE_START;
	for(i = 1; i < tr_dst->EventNum;i++) 
	{
		evattr = (char)((tr_dst->ep[i].EventType & 0xff00) >> 8);
		if(evattr == 'E' || evattr == 'O' || evattr == 'D')
			tr_dst->ep[i].EventType = EVENT_TYPE_END;
		else {
			event_type = tr_dst->ep[i].EventType & 0xff;
			if(event_type == '0')
				tr_dst->ep[i].EventType = EVENT_TYPE_NONREFLECT;
			else if(event_type == '1')
				tr_dst->ep[i].EventType = EVENT_TYPE_REFLECT;
			else
				tr_dst->ep[i].EventType = EVENT_TYPE_REFLECT;
		}
	}
	tr_dst->FiberNum = tr_src->FiberNum;
	memcpy(tr_dst->fs, tr_src->fs, tr_src->FiberNum*sizeof(FiberSection_t));
	memcpy(&tr_dst->FiberLen,&tr_src->FiberLen, sizeof(float)*4);
#if 0
	static int32_t index = 1;
	char file_name[128] = {0};
	sprintf(file_name,"%dM-%dNs-%dms-%d",tr_dst->tp.MeasureLength_m, tr_dst->tp.PulseWidth_ns,\
			tr_dst->tp.MeasureTime_ms,index++);
	PR_X("save data pt %s ",file_name);
	save_data_pt(file_name,tr_src->Ai,16000);
#endif
usr_exit:
	return 0;
}


/* --------------------------------------------------------------------------*/
/**
 * @synopsis 	cb_stop 
 * 			使用线程内全局变量作为通道号，根据通道状态确定返回值
 * 			并行otdr需要让每个通道都stop,串行otdr的stop通道无关
 *
 * @returns  0 或者 1 
 */
/* ----------------------------------------------------------------------------*/
int32_t cb_stop()
{
	return otdrTestCtrl.stop;
}
extern pthread_key_t key_ch;
int32_t cb_stop_paralle()
{
	int32_t ch,ret;
	ch = *((int *)pthread_getspecific(key_ch));
	ret = paralleCtrlBuf[ch].stop;
	if(ret != 0)
		PR_X("USR STOP ch(%d) stop(%d)\n",ch, ret);
	return ret;
}

/* --------------------------------------------------------------------------*/
/**
 * @synopsis  check_algro_tr 检查测量结果是否合法
 *
 * @param tr
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
int32_t check_algro_tr(const OtdrTestResult_t *tr)
{
	int32_t ret;
	ret = CMD_RET_PARA_INVLADE;

	if(tr->valid != 3){

		PR_X("not include test result %d\n", tr->valid);
		goto usr_exit;
	}
	if(tr->tp.DataNum != DATA_LEN){

		PR_X("data num illegality %d\n", tr->tp.DataNum);
		goto usr_exit;
	}
	if(tr->EventNum < 0 || tr->EventNum > MAX_EVENT_NUM){

		PR_X("event num illegality %d max num %d\n", tr->EventNum,MAX_EVENT_NUM);
		goto usr_exit;
	}
	if(tr->FiberNum < 0 || tr->FiberNum > MAX_EVENT_NUM){

		PR_X("fiber num illegality %d max num %d\n", tr->FiberNum,MAX_EVENT_NUM);
		goto usr_exit;
	}
	if(tr->FiberNum != (tr->EventNum - 1)){

		PR_X("fiber num illegality sec_num  %d event num %d\n", tr->FiberNum,tr->EventNum);
		goto usr_exit;
	}
	ret = 0;

usr_exit:
	return ret;

}
/* --------------------------------------------------------------------------*/
/**
 * @synopsis  convert_tr_host2algor 将光纤段配置转换成算法模块的格式
 *
 * @param pfibersec	光纤段配置
 * @param res 算法格式的曲线
 *
 * @returns   
 */
/* ----------------------------------------------------------------------------*/
int32_t convert_tr_fbsec2algor(struct _tagCHFiberSec *pfibersec,  OtdrTestResult_t *res)
{
	
	struct _tagHostOtdrPara host_para;
	struct _tagFiberSecCfg *ppara;
	ppara = &pfibersec->para;
	host_para.slot = ppara->otdr_param.slot;
	host_para.pipe = ppara->otdr_param.pipe;
	memcpy(&host_para.MeasureLength_m, &ppara->otdr_param.range, sizeof(struct _tagHostOtdrPara) - 8);
	
	res->valid = 48;
	convert_para_host2algor_v1(&res->tp,&host_para); 
	convert_result_host2algor(res, (struct _tagHostTestResult *)(&pfibersec->para.test_result.range));

	convert_event_hostalgor(res,(struct _tagOtdrEvent *) pfibersec->para.event_val, pfibersec->para.event_hdr.count,
			&host_para);
	convert_data_host2algor(res, (int32_t *)pfibersec->para.otdr_val, pfibersec->para.otdr_hdr.count);
	return 0;

}
int32_t convert_para_host2algor_v1(
		OtdrTestParam_t *palgor_para,
		 struct _tagHostOtdrPara *phost_para)
{
	palgor_para->EndThreshold = phost_para->EndThreshold;
	palgor_para->Lambda_nm = phost_para->Lambda_nm;
	palgor_para->MeasureLength_m = phost_para->MeasureLength_m;
	palgor_para->MeasureTime_ms = phost_para->MeasureTime_s*1000;
	palgor_para->NonReflex= phost_para->NonRelectThreshold ;
	palgor_para->PulseWidth_ns = phost_para->PulseWidth_ns;
	palgor_para->n = phost_para->n;
	palgor_para->ChanNum = phost_para->pipe;
	palgor_para->SampleRate_Hz = phost_para->sample_hz;
	palgor_para->rsvd1 = phost_para->rsv2;
	palgor_para->rsvd2 = phost_para->rsv3;

	return 0;
}
//曲线信息中的测量结果，算法-->协议模式
int32_t convert_result_host2algor(
		OtdrTestResult_t *tr, 
		struct _tagHostTestResult * pHostTr)
{
	tr->FiberAttenCoef = pHostTr->attu;
	tr->FiberLen = pHostTr->chain;
	tr->FiberLoss = pHostTr->loss;
	return 0;
}
//事件点，算法-->协议模式
int32_t convert_event_hostalgor(
		OtdrTestResult_t *tr,
		struct _tagOtdrEvent HostEptbuf[],
		int32_t ept_num, 
		struct _tagHostOtdrPara *phost_para)
{
	int32_t i,sample_hz, dis;
	float n;
	sample_hz = phost_para->sample_hz;
	n = phost_para->n;

	if(ept_num > MAX_EVENT_NUM)
		ept_num = MAX_EVENT_NUM;

	tr->EventNum = ept_num;
	tr->FiberNum = ept_num - 1;

	for(i = 0; i < ept_num - 1;i++)
	{	
		tr->ep[i].EventStart = HostEptbuf[i].distance;

		tr->ep[i].EventInsertloss = HostEptbuf[i].insert_loss;
		tr->ep[i].EventReturnloss = HostEptbuf[i].return_loss;
		tr->ep[i].EventTotalloss = HostEptbuf[i].total_loss;
		tr->fs[i].FiberSectionAttenCoef = HostEptbuf[i+1].attu;
		tr->fs[i].FiberSectionLen = HostEptbuf[i+1].distance - HostEptbuf[i].distance;
		if(tr->fs[i].FiberSectionAttenCoef < RSVD_FLOAT)
		{
			dis = getLenByIndex(tr->fs[i].FiberSectionLen,sample_hz, n);
			tr->fs[i].FiberSectionLoss = dis*tr->fs[i].FiberSectionAttenCoef/1000.0;
		}
		else
			tr->fs[i].FiberSectionLoss = RSVD_FLOAT;

	}
	tr->ep[i].EventStart = HostEptbuf[i].distance;

	tr->ep[i].EventInsertloss = HostEptbuf[i].insert_loss;
	tr->ep[i].EventReturnloss = HostEptbuf[i].return_loss;
	tr->ep[i].EventTotalloss = HostEptbuf[i].total_loss;
	return 0;

}
//数据点，算法-->协议模式
int32_t convert_data_host2algor(
		OtdrTestResult_t *tr,
		const uint16_t data_buf[],
		int data_num)
{
	int i;
	tr->tp.DataNum = data_num;

	for(i = 0; i < data_num;i++)
	{
		tr->Ai[i] = data_buf[i]/1000.0 ;
	}
	return 0;


}

/* --------------------------------------------------------------------------*/
/**
 * @synopsis  adpt_test_pulse 修正脉宽
 *
 * @param cur_fiber_len 当前测试长度
 * @param potdr_dev 通道otdrdev
 *
 * @returns  可用脉宽长度 
 */
/* ----------------------------------------------------------------------------*/
int32_t adpt_test_pulse(struct _tagOtdrDev *potdr_dev)
{
	int32_t st_pulse, pulse;
	int32_t cur_fiber_len;

	st_pulse = potdr_dev->ch_ctrl.st_pulse;
	pulse = st_pulse;
	cur_fiber_len = potdr_dev->ch_ctrl.cur_fiber_len;
	/*
	 * 如果光纤长度变为标准曲线原来的一半，开始修正脉宽，否则使用
	 * 标准曲线长度的脉宽
	 */
	if(cur_fiber_len >= 2*potdr_dev->ch_ctrl.st_fiber_len/3 || potdr_dev->ch_ctrl.test_count == 0)
		goto usr_exit;

	else if(cur_fiber_len >= 90000){
		if(st_pulse > 10000)
			pulse = 10000;
	}
	else if(cur_fiber_len >= 70000){
		if(st_pulse > 2560)
			pulse = 2560;
	}
	else if(cur_fiber_len >= 50000){
		if(st_pulse >= 1280)
			pulse = 1280;
	}
	else if(cur_fiber_len >= 30000){
		if(st_pulse >= 640)
			pulse = 640;
	}
	else if(cur_fiber_len >= 10000){
		if(st_pulse >= 320)
			pulse = 320;
	}
	else 
		pulse = 80;

usr_exit:

	return pulse;
}

struct _tagPulseHouse pulseHouse;
int32_t get_test_pulse(float loss ,int32_t type )
{
	int32_t i, ret_pulse, num;
	struct _tagDynaPulse *pulse_buf;
	char ctype;
	ctype = type & 0xff;
	ret_pulse = 0;
	num = pulseHouse.num;
	if(ctype == 'A' || ctype == 'B' )
		pulse_buf = pulseHouse.cdp;
	else
		pulse_buf = pulseHouse.pdp;


	for(i = 0; i < num;i++)
	{
		if( (pulse_buf[i].dyna - loss ) >= 9)
		{
			ret_pulse = pulse_buf[i].pulse;
			break;
		}

	}
	return ret_pulse;
}
int32_t init_dypulse()
{
	int32_t i, pulse,dync ;
	pulseHouse.num = DYNA_PULSE_NUM;
	pulseHouse.cdp[0].pulse = 80;
	pulseHouse.pdp[0].pulse = 80;
	for(i = 1; i < DYNA_PULSE_NUM;i++)
	{
		pulse = pulseHouse.cdp[i - 1].pulse * 2;
		pulseHouse.cdp[i].pulse = pulse;
		pulseHouse.pdp[i].pulse = pulse;
	}
	i = DYNA_PULSE_NUM - 1;
	pulseHouse.pdp[i].pulse = 10000;
	i = 0;
	//pulseHouse.pdp[i++].dyna = 12;
	pulseHouse.pdp[i++].dyna = 17;
	pulseHouse.pdp[i++].dyna = 19;
	pulseHouse.pdp[i++].dyna = 21;
	pulseHouse.pdp[i++].dyna = 24;
	pulseHouse.pdp[i++].dyna = 26;
	pulseHouse.pdp[i++].dyna = 30;
	pulseHouse.pdp[i++].dyna = 32;
	pulseHouse.pdp[i++].dyna = 34;

	i = 0;
	//pulseHouse.cdp[i++].dyna = 9;
	pulseHouse.cdp[i++].dyna = 11;
	pulseHouse.cdp[i++].dyna = 13;
	pulseHouse.cdp[i++].dyna = 15;
	pulseHouse.cdp[i++].dyna = 17;
	pulseHouse.cdp[i++].dyna = 19;
	pulseHouse.cdp[i++].dyna = 24;
	pulseHouse.cdp[i++].dyna = 27;
	pulseHouse.cdp[i++].dyna = 30;
	return 0;

}
float get_loss_with_m(float len_m, struct _tagSecLoss *psec_loss)
{
	int32_t i, num,len;
	float ret_loss;
	struct _tagSecLossVal *ploss;

	ret_loss = 0;
	ploss = &psec_loss->val;
	len = (int32_t)len_m;
	num = psec_loss->sec_num;
	for(i = 0; i < num; i++)
	{
		if(len < ploss[i].len)
		{
			ret_loss = ploss[i].loss;
			break;
		}
	}

	return ret_loss;

}
const float ALARM_SCALE = 0.67;
int32_t init_sec_loss_len(struct _tagSecLoss *psec_loss, OtdrTestResult_t *pch_tr, struct _tagCHFiberSec *pfiber_sec)
{
	int32_t i, hz, end, isec[5];
	int32_t sec_num = 4, tmp, max_line_b;
	int32_t min_line_a;
	float n, sec[5];
	struct tms_fibersection_val *pfiber_val;
	struct _tagSecLossVal *psec_loss_val;

	hz = pch_tr->tp.SampleRate_Hz;
	n = pch_tr->tp.n;
	i = 0;
	sec[i++] = 10000;
	sec[i++] = 30000;
	sec[i++] = 60000;
	sec[i++] = 80000;
	sec[i++] = 0;
	pfiber_val = pfiber_sec->para.fiber_val;
	tmp = pfiber_sec->para.fiber_hdr.count;
	max_line_b = pfiber_val[0].end_coor;
	min_line_a = pfiber_val[0].start_coor;
	//找出最大B标杆的位置
	for(i = 1; i < tmp; i++)
	{
		if(max_line_b > pfiber_val[i].end_coor)
			max_line_b = pfiber_val[i].end_coor;
		if(min_line_a < pfiber_val[i].start_coor)
			min_line_a = pfiber_val[i].start_coor;
	}
	//
	end = max_line_b * ALARM_SCALE;
	/*
	 * 2017-10-10 改用A标杆的位置作为将脉宽的距离
	*/
	//psec_loss->alarm_dis = getLenByIndex (end, hz, n);
	psec_loss->alarm_dis = getLenByIndex(min_line_a, hz, n);
	psec_loss_val = psec_loss->val;
	//转换成序号，默认是 10-80 如果B标杆2/3 大于80 则增加一个
	for(i = 0; i < sec_num; i++)
	{
		isec[i] = getIndexByLen(sec[i],hz, n);
		psec_loss_val[i].len = sec[i];

		if(isec[i] > end)
			break;
	}
	if(i == sec_num)	//end > 80km
	{
		isec[i] = end;
		psec_loss_val[i].len = getLenByIndex(end,hz,n);
	}
	else
		isec[i + 1] = 0;
	sec_num = i + 1;
	getTotalLoss(pch_tr,isec,sec,sec_num);
	psec_loss->sec_num = sec_num;
	for(i = 0; i < sec_num; i++)
	{
		psec_loss_val[i].loss = sec[i];
	}
	return 0;



}
int32_t get_test_pulse_v1(const struct _tagOtdrDev * potdr_dev, const OtdrTestResult_t *pch_tr)
{
	int32_t pulse;
	float total_loss;
	struct _tagCHCtrl *pch_ctrl;
	pch_ctrl = &potdr_dev->ch_ctrl;
	pulse = 0;
	total_loss = pch_tr->FiberLoss;
	if(total_loss >= RSVD_FLOAT)
		total_loss = get_loss_with_m(pch_tr->FiberLen,\
				&potdr_dev->ch_ctrl.sec_loss);

	pulse = get_test_pulse(total_loss, pch_ctrl->lamda_type);
	//如果脉宽比标准曲线脉宽要大，不降脉宽
	if(pulse > pch_ctrl->st_pulse)
		pulse = 0;
	return pulse;
}

//按照C风格编译
#ifdef __cplusplus
}
#endif
